package com.winit.schedule.job.tracker.repository.mongo;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import com.google.code.morphia.query.Query;
import com.winit.schedule.core.repository.LoggerRepository;
import com.winit.schedule.core.repository.constants.LogType;
import com.winit.schedule.core.repository.entity.LogEntity;
import com.winit.schedule.core.repository.entity.Page;
import com.winit.schedule.store.mongo.AbstractMongoRepository;

public class MongoLoggerRepository extends AbstractMongoRepository<LogEntity> implements LoggerRepository {

    @Override
    public void saveLogger(LogEntity entity) {
        ds.save(entity);
    }

    @Override
    public void saveLogger(List<LogEntity> entitys) {
        ds.save(entitys);
    }

    @Override
    public List<LogEntity> queryLogByJobId(String jobId) {
        Query<LogEntity> query = createQuery().field("jobId").equal(jobId);
        return query.asList();
    }

    public Page queryTaskTrackerLog(String taskTrackerUuid, long startTime, long endTime, int page, int rows) {
        Query<LogEntity> query = createQuery();
        query.field("taskTrackerUuid").exists();

        if (null != taskTrackerUuid && taskTrackerUuid.trim().length() > 0) {
            query.field("taskTrackerUuid").equal(taskTrackerUuid);
        }

        if (startTime > 0) {
            query.field("logTime").greaterThanOrEq(startTime);
        }

        if (endTime > 0) {
            query.field("logTime").lessThanOrEq(endTime);
        }

        long total = query.countAll();

        query.order("-logTime");

        int offset = (page - 1) * rows;
        query.offset(offset);
        query.limit(rows);

        return new Page(page, total, query.asList());

    }

    @Override
    public Page queryJobLog(String jobId, long startTime, long endTime, int page, int rows) {
        Query<LogEntity> query = createQuery();
        query.field("jobId").exists();
        query.field("logType").in(Arrays.asList(LogType.JOB_LOG));

        if (null != jobId && jobId.trim().length() > 0) {
            query.field("jobId").equal(jobId);
        }

        if (startTime > 0) {
            query.field("logTime").greaterThanOrEq(startTime);
        }

        if (endTime > 0) {
            query.field("logTime").lessThanOrEq(endTime);
        }

        long total = query.countAll();

        query.order("-logTime");

        int offset = (page - 1) * rows;
        query.offset(offset);
        query.limit(rows);

        return new Page(page, total, query.asList());
    }

    @Override
    public Page queryTaskTrackerDisconnectLog(String ip, long startTime, long endTime, int page, int rows) {
        Query<LogEntity> query = createQuery();
        query.field("logType").equal(LogType.TASKTRACKER_DISCONNECT);
        Pattern pattern = Pattern.compile("^" + ip + ".*$", Pattern.CASE_INSENSITIVE);
        if (null != ip && ip.trim().length() > 0) {
            query.filter("taskTrackerUuid", pattern);
        }

        if (startTime > 0) {
            query.field("logTime").greaterThanOrEq(startTime);
        }

        if (endTime > 0) {
            query.field("logTime").lessThanOrEq(endTime);
        }

        long total = query.countAll();

        query.order("-logTime");

        int offset = (page - 1) * rows;
        query.offset(offset);
        query.limit(rows);

        return new Page(page, total, query.asList());
    }

    @Override
    public Page queryTaskExeFailureLog(String jobId, String taskId, long startTime, long endTime, int page, int rows) {
        Query<LogEntity> query = createQuery();
        query.field("logType")
            .in(Arrays.asList(new LogType[] { LogType.TASK_EXE_FAILURE, LogType.TASK_RUNNER_FAILURE }));

        if (null != taskId && taskId.trim().length() > 0) {
            query.field("taskId").equal(taskId);
        }

        if (null != jobId && jobId.trim().length() > 0) {
            query.field("jobId").equal(jobId);
        }

        if (startTime > 0) {
            query.field("logTime").greaterThanOrEq(startTime);
        }

        if (endTime > 0) {
            query.field("logTime").lessThanOrEq(endTime);
        }

        long total = query.countAll();

        query.order("-logTime");

        int offset = (page - 1) * rows;
        query.offset(offset);
        query.limit(rows);

        return new Page(page, total, query.asList());
    }

    @Override
    public Page queryTaskLog(String jobId, String taskId, long startDate, long endDate, int page, int rows) {
        Query<LogEntity> query = createQuery();

        if (null != taskId && taskId.trim().length() > 0) {
            Pattern pattern = Pattern.compile(".*" + taskId + ".*", Pattern.CASE_INSENSITIVE);
            query.filter("taskId", pattern);
        } else {
            query.field("taskId").exists();
        }

        if (null != jobId && jobId.trim().length() > 0) {
            query.field("jobId").equal(jobId);
        }

        if (startDate > 0) {
            query.field("logTime").greaterThanOrEq(startDate);
        }

        if (endDate > 0) {
            query.field("logTime").lessThanOrEq(endDate);
        }

        long total = query.countAll();

        query.order("-logTime");

        int offset = (page - 1) * rows;
        query.offset(offset);
        query.limit(rows);

        return new Page(page, total, query.asList());
    }
}
